package legumes.client.ui.otherboxes;

import legumes.client.evt.main.UserConnectedEvent;
import legumes.client.evt.main.UserConnectedEventHandler;
import legumes.client.evt.main.UserDisconnectedEvent;
import legumes.client.evt.main.UserDisconnectedEventHandler;
import legumes.client.evt.manager.EventBusManager;
import legumes.client.resources.PNResources;
import legumes.client.services.callbacks.SetPasswordCallback;
import legumes.client.services.callbacks.UnlogCallback;
import legumes.client.services.callbacks.WhoAmICallback;
import legumes.client.services.util.rpc.RPCCallSequencer;
import legumes.client.ui.Authentication;
import legumes.client.ui.widgets.form.ConnexionForm;
import legumes.shared.domain.CustomerDTO;

import com.google.gwt.user.client.Cookies;
import com.smartgwt.client.types.Alignment;
import com.smartgwt.client.types.VerticalAlignment;
import com.smartgwt.client.util.SC;
import com.smartgwt.client.widgets.Window;
import com.smartgwt.client.widgets.form.DynamicForm;
import com.smartgwt.client.widgets.form.fields.ButtonItem;
import com.smartgwt.client.widgets.form.fields.LinkItem;
import com.smartgwt.client.widgets.form.fields.PasswordItem;
import com.smartgwt.client.widgets.form.fields.events.ClickEvent;
import com.smartgwt.client.widgets.form.fields.events.ClickHandler;
import com.smartgwt.client.widgets.layout.VLayout;

public class ConnexionBoxPanel extends Window {

	private ConnexionForm connexionForm;
	private DynamicForm logoutForm;
	private VLayout mainVLayout;
	private LinkItem logoutButton;
	private LinkItem changePasswordButton;
	
	public ConnexionBoxPanel() {
		super();
		buildGui();
		bind();
	}
	
	private void bind(){
		EventBusManager.getInstance().getEventBus().addHandler(
				UserConnectedEvent.TYPE, 
				new UserConnectedEventHandler(){

					@Override
					public void onUserConnected(UserConnectedEvent event) {
						if( isVisible() ){
							setVisible(false);
						}
					}
				});
		
		EventBusManager.getInstance().getEventBus().addHandler(
				UserDisconnectedEvent.TYPE, 
				new UserDisconnectedEventHandler(){

					@Override
					public void onUserDisconnected(UserDisconnectedEvent event) {
						if(! isVisible() ){
							setVisible(true);
						}
					}
				});
	}
	
	private void buildGui(){
		setWidth100();
		setHeight("195");
		setMargin(5);
		setTitle("<img src=\"" + PNResources.INSTANCE.userAloneIcon().getURL() + "\" />&nbsp;Connexion");
		setShowCloseButton(false);
        setShowMinimizeButton(true);
		setCanDrag(false);
		setCanDragReposition(false);
		
		connexionForm = new ConnexionForm(){
			protected void onUserConnected(CustomerDTO customer_){
				ConnexionBoxPanel.this.onUserConnected(customer_);
			}
		};
		
		mainVLayout = new VLayout();
		mainVLayout.setLayoutAlign(Alignment.CENTER);
		mainVLayout.setMembersMargin(5);
		mainVLayout.setAlign(Alignment.CENTER);
		mainVLayout.setAlign(VerticalAlignment.CENTER);
		mainVLayout.setWidth("*");
		mainVLayout.setHeight("*");
		
		changePasswordButton = new LinkItem();  
//		changePasswordButton.setWidth(200);
//		changePasswordButton.setLayoutAlign(Alignment.CENTER);
		changePasswordButton.setShowTitle(false);
		changePasswordButton.setLinkTitle("<img src=\"" + PNResources.INSTANCE.lockEditIcon().getURL() + "\" />&nbsp;<i>Changer le mot de passe...</i>");
        changePasswordButton.addClickHandler( new ClickHandler() {
			
			@Override
			public void onClick(ClickEvent event) {
				showChangePasswordDialog();
			}
		});
		
		logoutButton = new LinkItem();  
		logoutButton.setWidth(200);
//		logoutButton.setLayoutAlign(Alignment.CENTER);
		logoutButton.setShowTitle(false);
		logoutButton.setLinkTitle("<img src=\"" + PNResources.INSTANCE.unLockIcon().getURL() + "\" />&nbsp;<i>D&eacute;connexion...</i>");
		logoutButton.addClickHandler( new ClickHandler() {
			
			@Override
			public void onClick(ClickEvent event) {
				doLogout();
				connexionForm.resetPasswordFields();
				setFormVisible(connexionForm);
				setTitle("<img src=\"" + PNResources.INSTANCE.userAloneIcon().getURL() + "\" />&nbsp;Connexion");
			}
		});
		
		logoutForm = new DynamicForm();
		logoutForm.setNumCols(1);
		logoutForm.setFields(logoutButton, changePasswordButton);
		mainVLayout.setMembers(connexionForm);
		
		String sessionID = Cookies.getCookie("sid");
	    if ( sessionID != null ){ 
	    	checkWithServerIfSessionIdIsStillLegal();
	    }
	    else {
	    	addItem(mainVLayout);
	    }
	}

	private void checkWithServerIfSessionIdIsStillLegal() {
		RPCCallSequencer callSequencer = new RPCCallSequencer();
		final WhoAmICallback whoAmIallback = new WhoAmICallback();
		callSequencer.addCall(whoAmIallback);
		callSequencer.addRunnable(new Runnable() {
			public void run() {
				CustomerDTO customerDTO = whoAmIallback.getCustomerDTO();
				if( customerDTO == null ){
					addItem(mainVLayout);
				} else {
					Authentication.setCustomer(customerDTO);
					onUserConnected(customerDTO);
				}
			}
		});
		callSequencer.callSequence();
		addItem(mainVLayout);
	}


	protected void showChangePasswordDialog() {
		final Window dialogWindow = new Window();
		dialogWindow.setTitle("<img src=\"" + PNResources.INSTANCE.lockEditIcon().getURL() + "\" />&nbsp;Changer votre mot de passe");
		dialogWindow.setWidth(300);
		dialogWindow.setHeight(200);
		dialogWindow.setMargin(10);
		
		DynamicForm formPanel = new DynamicForm(); 
		formPanel.setWidth100();
		formPanel.setHeight100();
		formPanel.setMargin(5);
		formPanel.setNumCols(4);
		formPanel.setTitleWidth(200);
		
		final PasswordItem oldPassword = new PasswordItem("oldPassword", "Ancien mot de passe");
		oldPassword.setColSpan(4);
		final PasswordItem newPassword1 = new PasswordItem("newpassword1", "Nouveau mot de passe");
		newPassword1.setColSpan(4);
		final PasswordItem newPassword2 = new PasswordItem("newpassword2", "Confirmer le nouveau mot de passe");
		newPassword2.setColSpan(4);
		
		ButtonItem ok = new ButtonItem("ok", "OK");
		ok.setStartRow(true);
		ok.setEndRow(false);
		ok.setColSpan(2);
		ok.setAlign(Alignment.RIGHT);
		ok.setIcon(PNResources.INSTANCE.validateIcon().getURL());
		ok.addClickHandler(new ClickHandler() {
			
			@Override
			public void onClick(ClickEvent event) {
				if (!newPassword1.getValueAsString().equals(
						newPassword2.getValueAsString())) {
					SC.warn("Le nouveau mot de passe n'est pas identique dans les deux champs de saisie !<br>"
									+ "Merci de les saisir à nouveau.");
					return;
				}

				RPCCallSequencer callSequencer = new RPCCallSequencer();

				final SetPasswordCallback setPasswordCallback = new SetPasswordCallback(
						oldPassword.getValueAsString(), newPassword1
								.getValueAsString());
				callSequencer.addCall(setPasswordCallback);

				callSequencer.addRunnable(new Runnable() {
					public void run() {
						if (setPasswordCallback.getLoginException() != null) {
							SC.warn(setPasswordCallback
									.getLoginException().getMessage());
						} else {
							dialogWindow.hide();
							SC.say("Mot de passe",
									"Votre de passe a été changé avec succès.");
						}
					}
				});
				callSequencer.callSequence();
			}
		});
		
		ButtonItem cancel = new ButtonItem("cancel", "Annuler");
		cancel.setStartRow(false);
		cancel.setAlign(Alignment.RIGHT);
		cancel.setColSpan(2);
		cancel.setIcon(PNResources.INSTANCE.cancelIcon().getURL());
		cancel.addClickHandler(new ClickHandler() {
			
			@Override
			public void onClick(ClickEvent event) {
				dialogWindow.hide();
			}
		});
		
		
		formPanel.setItems(oldPassword, newPassword1, newPassword2, 
				ok, cancel);
		
		dialogWindow.addItem(formPanel);
		dialogWindow.setShowMinimizeButton(false);
		dialogWindow.setShowCloseButton(false);
		dialogWindow.setAutoCenter(true);
		dialogWindow.draw();
		oldPassword.focusInItem();
	}
	
	private void onUserConnected(CustomerDTO customer_){
		EventBusManager.getInstance().getEventBus().fireEvent(new UserConnectedEvent(customer_));
		setFormVisible(logoutForm);
		setTitle("<img src=\"" + PNResources.INSTANCE.userAloneIcon().getURL() + "\" />&nbsp;Bienvenue " + customer_.getName() + " !");
	}
	
	private void setFormVisible(DynamicForm df_){
		mainVLayout.setMembers(df_);
		if(df_==connexionForm){
			setHeight("195");
		} else {
			setHeight("100");
		}
		markForRedraw();
	}
	
	private void doLogout(){
		final RPCCallSequencer callSequencer = new RPCCallSequencer();
		callSequencer.addCall(new UnlogCallback());
		callSequencer.addRunnable(new Runnable() {
			public void run() {
				EventBusManager.getInstance().getEventBus().fireEvent(
						new UserDisconnectedEvent(Authentication.getCustomer()));
				Authentication.setCustomer(null);
			}
		});
		callSequencer.callSequence();
	}
}
